package com.decent.core.alarm.process;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.json.JSONUtil;
import com.decent.common.bo.MessageBean;
import com.decent.common.enums.ErrorCodeEnum;
import com.decent.common.exception.ErrorCodeException;
import com.decent.core.alarm.config.AlarmInternalConfig;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.util.List;

/**
 * 报警业务流程执行器
 * 注意当前流程执行器的注入方式
 * <p>
 * 调用示例:
 * ProcessContext process = processController.process(ProcessContext.builder()
 * .bizCode(BizCodeEnum.COMMON_SEND)
 * // 默认不中断流程,若处理流程中出现异常则该字段被替换为true
 * .needBreak(false)
 * .processModel(SendMsgModel.builder()
 * .companyId(user.getCompanyId())
 * .params(OrderOverSoldParams.builder()
 * .date(LocalDateTimeUtil.now())
 * .productName("卫龙 麻辣味馋魔芋爽素毛肚 18g/袋")
 * .storeName("飞龙天润大厦店")
 * .build())
 * .build())
 * // 处理成功时的响应,若处理流程中出现异常则该响应被替换
 * .response(MessageBean.success()).build());
 * return process.getResponse();
 *
 * @author menghx
 * @see AlarmInternalConfig#processController()
 */
@Slf4j
@Data
public class AlarmProcessExecutor {

    /**
     * 模板映射
     *
     * @see AlarmInternalConfig#commonAlarmTemplate()
     * @see AlarmInternalConfig#processController()
     */
    private AlarmProcessTemplate alarmProcessTemplate = null;


    /**
     * 执行责任链
     *
     * @param context 上下文内容
     * @return 返回上下文内容
     */
    public AlarmProcessContext process(AlarmProcessContext context) {
        // 前置检查
        if (!preCheck(context)) {
            return context;
        }
        // 遍历流程节点
        List<AlarmBusiness> processList = alarmProcessTemplate.getProcessList();
        for (AlarmBusiness alarmBusiness : processList) {
            alarmBusiness.process(context);
            if (context.getNeedBreak() == null || context.getNeedBreak()) {
                log.info("流程节点中断,[{}],context[{}]", ClassUtil.getClassName(alarmBusiness, true), JSONUtil.toJsonStr(context));
                break;
            }
        }
        return context;
    }

    /**
     * 前置检查
     *
     * @param context 上下文
     * @return 检查是否通过
     */
    private Boolean preCheck(AlarmProcessContext context) {
        // 上下文
        if (context == null) {
            throw new ErrorCodeException(ErrorCodeEnum.CONTEXT_IS_NULL);
        }
        // 执行模板
        AlarmProcessTemplate alarmProcessTemplate = this.getAlarmProcessTemplate();
        if (alarmProcessTemplate == null) {
            context.setResponse(MessageBean.fail(ErrorCodeEnum.PROCESS_TEMPLATE_IS_NULL));
            return false;
        }
        // 执行模板列表
        List<AlarmBusiness> processList = alarmProcessTemplate.getProcessList();
        if (CollUtil.isEmpty(processList)) {
            context.setResponse(MessageBean.fail(ErrorCodeEnum.PROCESS_LIST_IS_NULL));
            return false;
        }
        return true;
    }


}
